home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 May / maximum-cd-2009-05.iso / DiscContents / Firefox Setup 3.0.6.exe / nonlocalized / chrome / toolkit.jar / content / mozapps / plugins / pluginInstallerWizard.js < prev    next >
Encoding:
JavaScript  |  2008-05-28  |  23.7 KB  |  683 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Plugin Finder Service.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * IBM Corporation.
  18.  * Portions created by the IBM Corporation are Copyright (C) 2004
  19.  * IBM Corporation. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Doron Rosenberg <doronr@us.ibm.com>
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38. function nsPluginInstallerWizard(){
  39.  
  40.   // create the request array
  41.   this.mPluginRequestArray = new Object();
  42.   // since the array is a hash, store the length
  43.   this.mPluginRequestArrayLength = 0;
  44.  
  45.   // create the plugin info array.
  46.   // a hash indexed by plugin id so we don't install 
  47.   // the same plugin more than once.
  48.   this.mPluginInfoArray = new Object();
  49.   this.mPluginInfoArrayLength = 0;
  50.  
  51.   // holds plugins we couldn't find
  52.   this.mPluginNotFoundArray = new Object();
  53.   this.mPluginNotFoundArrayLength = 0;
  54.  
  55.   // array holding pids of plugins that require a license
  56.   this.mPluginLicenseArray = new Array();
  57.  
  58.   // how many plugins are to be installed
  59.   this.pluginsToInstallNum = 0;
  60.  
  61.   this.mBrowser = null;
  62.   this.mSuccessfullPluginInstallation = 0;
  63.   this.mNeedsRestart = false;
  64.  
  65.   // arguments[0] is an array that contains two items:
  66.   //     an array of mimetypes that are missing
  67.   //     a reference to the browser that needs them, 
  68.   //        so we can notify which browser can be reloaded.
  69.  
  70.   if ("arguments" in window) {
  71.     for (var item in window.arguments[0].plugins){
  72.       this.mPluginRequestArray[window.arguments[0].plugins[item].mimetype] =
  73.         new nsPluginRequest(window.arguments[0].plugins[item]);
  74.  
  75.       this.mPluginRequestArrayLength++;
  76.     }
  77.  
  78.     this.mBrowser = window.arguments[0].browser;
  79.   }
  80.  
  81.   this.WSPluginCounter = 0;
  82.   this.licenseAcceptCounter = 0;
  83.  
  84.   this.prefBranch = null;
  85. }
  86.  
  87. nsPluginInstallerWizard.prototype.getPluginData = function (){
  88.   // for each mPluginRequestArray item, call the datasource
  89.   this.WSPluginCounter = 0;
  90.  
  91.   // initiate the datasource call
  92.   var rdfUpdater = new nsRDFItemUpdater(this.getOS(), this.getChromeLocale());
  93.  
  94.   for (item in this.mPluginRequestArray) {
  95.     rdfUpdater.checkForPlugin(this.mPluginRequestArray[item]);
  96.   }
  97. }
  98.  
  99. // aPluginInfo is null if the datasource call failed, and pid is -1 if
  100. // no matching plugin was found.
  101. nsPluginInstallerWizard.prototype.pluginInfoReceived = function (aPluginInfo){
  102.   this.WSPluginCounter++;
  103.  
  104.   if (aPluginInfo && (aPluginInfo.pid != -1) ) {
  105.     // hash by id
  106.     this.mPluginInfoArray[aPluginInfo.pid] = new PluginInfo(aPluginInfo);
  107.     this.mPluginInfoArrayLength++;
  108.   } else {
  109.     this.mPluginNotFoundArray[aPluginInfo.requestedMimetype] = new PluginInfo(aPluginInfo);
  110.     this.mPluginNotFoundArrayLength++;
  111.   }
  112.  
  113.   var progressMeter = document.getElementById("ws_request_progress");
  114.  
  115.   if (progressMeter.getAttribute("mode") == "undetermined")
  116.     progressMeter.setAttribute("mode", "determined");
  117.  
  118.   progressMeter.setAttribute("value",
  119.       ((this.WSPluginCounter / this.mPluginRequestArrayLength) * 100) + "%");
  120.  
  121.   if (this.WSPluginCounter == this.mPluginRequestArrayLength) {
  122.     // check if no plugins were found
  123.     if (this.mPluginInfoArrayLength == 0) {
  124.       this.advancePage("lastpage");
  125.     } else {
  126.       this.advancePage(null);
  127.     }
  128.   } else {
  129.     // process more.
  130.   }
  131. }
  132.  
  133. nsPluginInstallerWizard.prototype.showPluginList = function (){
  134.   var myPluginList = document.getElementById("pluginList");
  135.   var hasPluginWithInstallerUI = false;
  136.  
  137.   // clear children
  138.   for (var run = myPluginList.childNodes.length; run > 0; run--)
  139.     myPluginList.removeChild(myPluginList.childNodes.item(run));
  140.  
  141.   this.pluginsToInstallNum = 0;
  142.  
  143.   for (pluginInfoItem in this.mPluginInfoArray){
  144.     // [plugin image] [Plugin_Name Plugin_Version]
  145.  
  146.     var pluginInfo = this.mPluginInfoArray[pluginInfoItem];
  147.  
  148.     // create the checkbox
  149.     var myCheckbox = document.createElement("checkbox");
  150.     myCheckbox.setAttribute("checked", "true");
  151.     myCheckbox.setAttribute("oncommand", "gPluginInstaller.toggleInstallPlugin('" + pluginInfo.pid + "', this)");
  152.     // XXXlocalize (nit)
  153.     myCheckbox.setAttribute("label", pluginInfo.name + " " + (pluginInfo.version ? pluginInfo.version : ""));
  154.     myCheckbox.setAttribute("src", pluginInfo.IconUrl);
  155.  
  156.     myPluginList.appendChild(myCheckbox);
  157.  
  158.     if (pluginInfo.InstallerShowsUI == "true")
  159.       hasPluginWithInstallerUI = true;
  160.  
  161.     // keep a running count of plugins the user wants to install
  162.     this.pluginsToInstallNum++;
  163.   }
  164.  
  165.   if (hasPluginWithInstallerUI)
  166.     document.getElementById("installerUI").hidden = false;
  167.  
  168.   this.canAdvance(true);
  169.   this.canRewind(false);
  170. }
  171.  
  172. nsPluginInstallerWizard.prototype.toggleInstallPlugin = function (aPid, aCheckbox) {
  173.   this.mPluginInfoArray[aPid].toBeInstalled = aCheckbox.checked;
  174.  
  175.   // if no plugins are checked, don't allow to advance
  176.   this.pluginsToInstallNum = 0;
  177.   for (pluginInfoItem in this.mPluginInfoArray){
  178.     if (this.mPluginInfoArray[pluginInfoItem].toBeInstalled)
  179.       this.pluginsToInstallNum++;
  180.   }
  181.  
  182.   if (this.pluginsToInstallNum > 0)
  183.     this.canAdvance(true);
  184.   else
  185.     this.canAdvance(false);
  186. }
  187.  
  188. nsPluginInstallerWizard.prototype.canAdvance = function (aBool){
  189.   document.getElementById("plugin-installer-wizard").canAdvance = aBool;
  190. }
  191.  
  192. nsPluginInstallerWizard.prototype.canRewind = function (aBool){
  193.   document.getElementById("plugin-installer-wizard").canRewind = aBool;
  194. }
  195.  
  196. nsPluginInstallerWizard.prototype.canCancel = function (aBool){
  197.   document.documentElement.getButton("cancel").disabled = !aBool;
  198. }
  199.  
  200. nsPluginInstallerWizard.prototype.showLicenses = function (){
  201.   this.canAdvance(false);
  202.   this.canRewind(false);
  203.  
  204.   // only add if a license is provided and the plugin was selected to
  205.   // be installed
  206.   for (pluginInfoItem in this.mPluginInfoArray){
  207.     var myPluginInfoItem = this.mPluginInfoArray[pluginInfoItem];
  208.     if (myPluginInfoItem.toBeInstalled && myPluginInfoItem.licenseURL && (myPluginInfoItem.licenseURL != ""))
  209.       this.mPluginLicenseArray.push(myPluginInfoItem.pid);
  210.   }
  211.  
  212.   if (this.mPluginLicenseArray.length == 0) {
  213.     // no plugins require licenses
  214.     this.advancePage(null);
  215.   } else {
  216.     this.licenseAcceptCounter = 0;
  217.  
  218.     // add a nsIWebProgress listener to the license iframe.
  219.     var docShell = document.getElementById("licenseIFrame").docShell;
  220.     var iiReq = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
  221.     var webProgress = iiReq.getInterface(Components.interfaces.nsIWebProgress);
  222.     webProgress.addProgressListener(gPluginInstaller.progressListener,
  223.                                     Components.interfaces.nsIWebProgress.NOTIFY_ALL);
  224.  
  225.     this.showLicense();
  226.   }
  227. }
  228.  
  229. nsPluginInstallerWizard.prototype.enableNext = function (){
  230.   // if only one plugin exists, don't enable the next button until
  231.   // the license is accepted
  232.   if (gPluginInstaller.pluginsToInstallNum > 1)
  233.     gPluginInstaller.canAdvance(true);
  234.  
  235.   document.getElementById("licenseRadioGroup1").disabled = false;
  236.   document.getElementById("licenseRadioGroup2").disabled = false;
  237. }
  238.  
  239. const nsIWebProgressListener = Components.interfaces.nsIWebProgressListener;
  240. nsPluginInstallerWizard.prototype.progressListener = {
  241.   onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
  242.   {
  243.     if ((aStateFlags & nsIWebProgressListener.STATE_STOP) &&
  244.        (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK)) {
  245.       // iframe loaded
  246.       gPluginInstaller.enableNext();
  247.     }
  248.   },
  249.  
  250.   onProgressChange : function(aWebProgress, aRequest, aCurSelfProgress,
  251.                               aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
  252.   {},
  253.   onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
  254.   {},
  255.  
  256.   QueryInterface : function(aIID)
  257.   {
  258.      if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
  259.          aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
  260.          aIID.equals(Components.interfaces.nsISupports))
  261.        return this;
  262.      throw Components.results.NS_NOINTERFACE;
  263.    }
  264. }
  265.  
  266. nsPluginInstallerWizard.prototype.showLicense = function (){
  267.   var pluginInfo = this.mPluginInfoArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
  268.  
  269.   this.canAdvance(false);
  270.  
  271.   loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE;
  272.   document.getElementById("licenseIFrame").webNavigation.loadURI(pluginInfo.licenseURL, loadFlags, null, null, null);
  273.  
  274.   document.getElementById("pluginLicenseLabel").firstChild.nodeValue = 
  275.     this.getFormattedString("pluginLicenseAgreement.label", [pluginInfo.name]);
  276.  
  277.   document.getElementById("licenseRadioGroup1").disabled = true;
  278.   document.getElementById("licenseRadioGroup2").disabled = true;
  279.   document.getElementById("licenseRadioGroup").selectedIndex = 
  280.     pluginInfo.licenseAccepted ? 0 : 1;
  281. }
  282.  
  283. nsPluginInstallerWizard.prototype.showNextLicense = function (){
  284.   var rv = true;
  285.  
  286.   if (this.mPluginLicenseArray.length > 0) {
  287.     this.storeLicenseRadioGroup();
  288.  
  289.     this.licenseAcceptCounter++;
  290.  
  291.     if (this.licenseAcceptCounter < this.mPluginLicenseArray.length) {
  292.       this.showLicense();
  293.  
  294.       rv = false;
  295.       this.canRewind(true);
  296.     }
  297.   }
  298.  
  299.   return rv;
  300. }
  301.  
  302. nsPluginInstallerWizard.prototype.showPreviousLicense = function (){
  303.   this.storeLicenseRadioGroup();
  304.   this.licenseAcceptCounter--;
  305.  
  306.   if (this.licenseAcceptCounter > 0)
  307.     this.canRewind(true);
  308.   else
  309.     this.canRewind(false);
  310.  
  311.   this.showLicense();
  312.   
  313.   // don't allow to return from the license screens
  314.   return false;
  315. }
  316.  
  317. nsPluginInstallerWizard.prototype.storeLicenseRadioGroup = function (){
  318.   var pluginInfo = this.mPluginInfoArray[this.mPluginLicenseArray[this.licenseAcceptCounter]];
  319.   pluginInfo.licenseAccepted = !document.getElementById("licenseRadioGroup").selectedIndex;
  320. }
  321.  
  322. nsPluginInstallerWizard.prototype.licenseRadioGroupChange = function(aAccepted) {
  323.   // only if one plugin is to be installed should selection change the next button
  324.   if (this.pluginsToInstallNum == 1)
  325.     this.canAdvance(aAccepted);
  326. }
  327.  
  328. nsPluginInstallerWizard.prototype.advancePage = function (aPageId){
  329.   this.canAdvance(true);
  330.   document.getElementById("plugin-installer-wizard").advance(aPageId);
  331. }
  332.  
  333. nsPluginInstallerWizard.prototype.startPluginInstallation = function (){
  334.   this.canAdvance(false);
  335.   this.canRewind(false);
  336.  
  337.   var installerPlugins = [];
  338.   var xpiPlugins = [];
  339.  
  340.   for (pluginInfoItem in this.mPluginInfoArray){
  341.     var pluginItem = this.mPluginInfoArray[pluginInfoItem];
  342.  
  343.     if (pluginItem.toBeInstalled && pluginItem.licenseAccepted) {
  344.       if (pluginItem.InstallerLocation)
  345.         installerPlugins.push(pluginItem);
  346.       else if (pluginItem.XPILocation)
  347.         xpiPlugins.push(pluginItem);
  348.     }
  349.   }
  350.  
  351.   if (installerPlugins.length > 0 || xpiPlugins.length > 0)
  352.     PluginInstallService.startPluginInstallation(installerPlugins,
  353.                                                  xpiPlugins);
  354.   else
  355.     this.advancePage(null);
  356. }
  357.  
  358. /*
  359.   0    starting download
  360.   1    download finished
  361.   2    starting installation
  362.   3    finished installation
  363.   4    all done
  364. */
  365. nsPluginInstallerWizard.prototype.pluginInstallationProgress = function (aPid, aProgress, aError) {
  366.  
  367.   var statMsg = null;
  368.   var pluginInfo = gPluginInstaller.mPluginInfoArray[aPid];
  369.  
  370.   switch (aProgress) {
  371.  
  372.     case 0:
  373.       statMsg = this.getFormattedString("pluginInstallation.download.start", [pluginInfo.name]);
  374.       break;
  375.  
  376.     case 1:
  377.       statMsg = this.getFormattedString("pluginInstallation.download.finish", [pluginInfo.name]);
  378.       break;
  379.  
  380.     case 2:
  381.       statMsg = this.getFormattedString("pluginInstallation.install.start", [pluginInfo.name]);
  382.       break;
  383.  
  384.     case 3:
  385.       if (aError) {
  386.         statMsg = this.getFormattedString("pluginInstallation.install.error", [pluginInfo.name, aError]);
  387.         pluginInfo.error = aError;
  388.       } else {
  389.         statMsg = this.getFormattedString("pluginInstallation.install.finish", [pluginInfo.name]);
  390.         pluginInfo.error = null;
  391.       }
  392.       break;
  393.  
  394.     case 4:
  395.       statMsg = this.getString("pluginInstallation.complete");
  396.       break;
  397.   }
  398.  
  399.   if (statMsg)
  400.     document.getElementById("plugin_install_progress_message").value = statMsg;
  401.  
  402.   if (aProgress == 4) {
  403.     this.advancePage(null);
  404.   }
  405. }
  406.  
  407. nsPluginInstallerWizard.prototype.pluginInstallationProgressMeter = function (aPid, aValue, aMaxValue){
  408.   var progressElm = document.getElementById("plugin_install_progress");
  409.  
  410.   if (progressElm.getAttribute("mode") == "undetermined")
  411.     progressElm.setAttribute("mode", "determined");
  412.   
  413.   progressElm.setAttribute("value", Math.ceil((aValue / aMaxValue) * 100) + "%")
  414. }
  415.  
  416. nsPluginInstallerWizard.prototype.addPluginResultRow = function (aImgSrc, aName, aNameTooltip, aStatus, aStatusTooltip, aManualUrl){
  417.   var myRows = document.getElementById("pluginResultList");
  418.  
  419.   var myRow = document.createElement("row");
  420.   myRow.setAttribute("align", "center");
  421.  
  422.   // create the image
  423.   var myImage = document.createElement("image");
  424.   myImage.setAttribute("src", aImgSrc);
  425.   myImage.setAttribute("height", "16px");
  426.   myImage.setAttribute("width", "16px");
  427.   myRow.appendChild(myImage)
  428.  
  429.   // create the labels
  430.   var myLabel = document.createElement("label");
  431.   myLabel.setAttribute("value", aName);
  432.   if (aNameTooltip)
  433.     myLabel.setAttribute("tooltiptext", aNameTooltip);
  434.   myRow.appendChild(myLabel);
  435.  
  436.   if (aStatus) {
  437.     myLabel = document.createElement("label");
  438.     myLabel.setAttribute("value", aStatus);
  439.     myRow.appendChild(myLabel);
  440.   }
  441.  
  442.   // manual install
  443.   if (aManualUrl) {
  444.     var myButton = document.createElement("button");
  445.  
  446.     var manualInstallLabel = this.getString("pluginInstallationSummary.manualInstall.label");
  447.     var manualInstallTooltip = this.getString("pluginInstallationSummary.manualInstall.tooltip");
  448.  
  449.     myButton.setAttribute("label", manualInstallLabel);
  450.     myButton.setAttribute("tooltiptext", manualInstallTooltip);
  451.  
  452.     myRow.appendChild(myButton);
  453.  
  454.     // XXX: XUL sucks, need to add the listener after it got added into the document
  455.     if (aManualUrl)
  456.       myButton.addEventListener("command", function() { gPluginInstaller.loadURL(aManualUrl) }, false);
  457.   }
  458.  
  459.   myRows.appendChild(myRow);
  460. }
  461.  
  462. nsPluginInstallerWizard.prototype.showPluginResults = function (){
  463.   var notInstalledList = "?action=missingplugins";
  464.   var myRows = document.getElementById("pluginResultList");
  465.  
  466.   // clear children
  467.   for (var run = myRows.childNodes.length; run--; run > 0)
  468.     myRows.removeChild(myRows.childNodes.item(run));
  469.  
  470.   for (pluginInfoItem in this.mPluginInfoArray){
  471.     // [plugin image] [Plugin_Name Plugin_Version] [Success/Failed] [Manual Install (if Failed)]
  472.  
  473.     var myPluginItem = this.mPluginInfoArray[pluginInfoItem];
  474.  
  475.     if (myPluginItem.toBeInstalled) {
  476.       var statusMsg;
  477.       var statusTooltip;
  478.       if (myPluginItem.error){
  479.         statusMsg = this.getString("pluginInstallationSummary.failed");
  480.         statusTooltip = myPluginItem.error;
  481.         notInstalledList += "&mimetype=" + pluginInfoItem;
  482.       } else if (!myPluginItem.licenseAccepted) {
  483.         statusMsg = this.getString("pluginInstallationSummary.licenseNotAccepted");
  484.       } else if (!myPluginItem.XPILocation) {
  485.         statusMsg = this.getString("pluginInstallationSummary.notAvailable");
  486.         notInstalledList += "&mimetype=" + pluginInfoItem;
  487.       } else {
  488.         this.mSuccessfullPluginInstallation++;
  489.         statusMsg = this.getString("pluginInstallationSummary.success");
  490.  
  491.         // only check needsRestart if the plugin was successfully installed.
  492.         if (myPluginItem.needsRestart)
  493.           this.mNeedsRestart = true;
  494.       }
  495.  
  496.       // manual url - either returned from the webservice or the pluginspage attribute
  497.       var manualUrl;
  498.       if ((myPluginItem.error || !myPluginItem.XPILocation) && (myPluginItem.manualInstallationURL || this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage)){
  499.         manualUrl = myPluginItem.manualInstallationURL ? myPluginItem.manualInstallationURL : this.mPluginRequestArray[myPluginItem.requestedMimetype].pluginsPage;
  500.       }
  501.  
  502.       this.addPluginResultRow(
  503.           myPluginItem.IconUrl, 
  504.           myPluginItem.name + " " + (myPluginItem.version ? myPluginItem.version : ""),
  505.           null,
  506.           statusMsg, 
  507.           statusTooltip,
  508.           manualUrl);
  509.     }
  510.   }
  511.  
  512.   // handle plugins we couldn't find
  513.   for (pluginInfoItem in this.mPluginNotFoundArray){
  514.     var pluginRequest = this.mPluginRequestArray[pluginInfoItem];
  515.  
  516.     // if there is a pluginspage, show UI
  517.     if (pluginRequest) {
  518.       this.addPluginResultRow(
  519.           "",
  520.           this.getFormattedString("pluginInstallation.unknownPlugin", [pluginInfoItem]),
  521.           null,
  522.           null,
  523.           null,
  524.           pluginRequest.pluginsPage);
  525.     }
  526.  
  527.     notInstalledList += "&mimetype=" + pluginInfoItem;
  528.   }
  529.  
  530.   // no plugins were found, so change the description of the final page.
  531.   if (this.mPluginInfoArrayLength == 0) {
  532.     var noPluginsFound = this.getString("pluginInstallation.noPluginsFound");
  533.     document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsFound);
  534.   } else if (this.mSuccessfullPluginInstallation == 0) {
  535.     // plugins found, but none were installed.
  536.     var noPluginsInstalled = this.getString("pluginInstallation.noPluginsInstalled");
  537.     document.getElementById("pluginSummaryDescription").setAttribute("value", noPluginsInstalled);
  538.   }
  539.  
  540.   document.getElementById("pluginSummaryRestartNeeded").hidden = !this.mNeedsRestart;
  541.  
  542.   var app = Components.classes["@mozilla.org/xre/app-info;1"]
  543.                       .getService(Components.interfaces.nsIXULAppInfo);
  544.  
  545.   // set the get more info link to contain the mimetypes we couldn't install.
  546.   notInstalledList +=
  547.     "&appID=" + app.ID +
  548.     "&appVersion=" + app.platformBuildID +
  549.     "&clientOS=" + this.getOS() +
  550.     "&chromeLocale=" + this.getChromeLocale() +
  551.     "&appRelease=" + app.version;
  552.  
  553.   document.getElementById("moreInfoLink").addEventListener("click", function() { gPluginInstaller.loadURL("https://pfs.mozilla.org/plugins/" + notInstalledList) }, false);
  554.  
  555.   if (this.mNeedsRestart) {
  556.     var cancel = document.getElementById("plugin-installer-wizard").getButton("cancel");
  557.     cancel.label = this.getString("pluginInstallation.close.label");
  558.     cancel.accessKey = this.getString("pluginInstallation.close.accesskey");
  559.     var finish = document.getElementById("plugin-installer-wizard").getButton("finish");
  560.     finish.label = this.getFormattedString("pluginInstallation.restart.label", [app.name]);
  561.     finish.accessKey = this.getString("pluginInstallation.restart.accesskey");
  562.     this.canCancel(true);
  563.   }
  564.   else {
  565.     this.canCancel(false);
  566.   }
  567.   this.canAdvance(true);
  568.   this.canRewind(false);
  569. }
  570.  
  571. nsPluginInstallerWizard.prototype.loadURL = function (aUrl){
  572.   // Check if the page where the plugin came from can load aUrl before
  573.   // loading it, and do *not* allow loading URIs that would inherit our
  574.   // principal.
  575.   
  576.   var pluginPagePrincipal =
  577.     window.opener.content.document.nodePrincipal;
  578.  
  579.   const nsIScriptSecurityManager =
  580.     Components.interfaces.nsIScriptSecurityManager;
  581.   var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
  582.                          .getService(nsIScriptSecurityManager);
  583.  
  584.   secMan.checkLoadURIStrWithPrincipal(pluginPagePrincipal, aUrl,
  585.     nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL);
  586.  
  587.   window.opener.open(aUrl);
  588. }
  589.  
  590. nsPluginInstallerWizard.prototype.getString = function (aName){
  591.   return document.getElementById("pluginWizardString").getString(aName);
  592. }
  593.  
  594. nsPluginInstallerWizard.prototype.getFormattedString = function (aName, aArray){
  595.   return document.getElementById("pluginWizardString").getFormattedString(aName, aArray);
  596. }
  597.  
  598. nsPluginInstallerWizard.prototype.getOS = function (){
  599.   var httpService = Components.classes["@mozilla.org/network/protocol;1?name=http"]
  600.                               .getService(Components.interfaces.nsIHttpProtocolHandler);
  601.   return httpService.oscpu;
  602. }
  603.  
  604. nsPluginInstallerWizard.prototype.getChromeLocale = function (){
  605.   var chromeReg = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
  606.                             .getService(Components.interfaces.nsIXULChromeRegistry);
  607.   return chromeReg.getSelectedLocale("global");
  608. }
  609.  
  610. nsPluginInstallerWizard.prototype.getPrefBranch = function (){
  611.   if (!this.prefBranch)
  612.     this.prefBranch = Components.classes["@mozilla.org/preferences-service;1"]
  613.                                 .getService(Components.interfaces.nsIPrefBranch);
  614.   return this.prefBranch;
  615. }
  616. function nsPluginRequest(aPlugRequest){
  617.   this.mimetype = encodeURI(aPlugRequest.mimetype);
  618.   this.pluginsPage = aPlugRequest.pluginsPage;
  619. }
  620.  
  621. function PluginInfo(aResult) {
  622.   this.name = aResult.name;
  623.   this.pid = aResult.pid;
  624.   this.version = aResult.version;
  625.   this.IconUrl = aResult.IconUrl;
  626.   this.InstallerLocation = aResult.InstallerLocation;
  627.   this.InstallerHash = aResult.InstallerHash;
  628.   this.XPILocation = aResult.XPILocation;
  629.   this.XPIHash = aResult.XPIHash;
  630.   this.InstallerShowsUI = aResult.InstallerShowsUI;
  631.   this.manualInstallationURL = aResult.manualInstallationURL;
  632.   this.requestedMimetype = aResult.requestedMimetype;
  633.   this.licenseURL = aResult.licenseURL;
  634.   this.needsRestart = (aResult.needsRestart == "true");
  635.  
  636.   this.error = null;
  637.   this.toBeInstalled = true;
  638.  
  639.   // no license provided, make it accepted
  640.   this.licenseAccepted = this.licenseURL ? false : true;
  641. }
  642.  
  643. var gPluginInstaller;
  644.  
  645. function wizardInit(){
  646.   gPluginInstaller = new nsPluginInstallerWizard();
  647.   gPluginInstaller.canAdvance(false);
  648.   gPluginInstaller.getPluginData();
  649. }
  650.  
  651. function wizardFinish(){
  652.   if (gPluginInstaller.mNeedsRestart) {
  653.     // Notify all windows that an application quit has been requested.
  654.     var os = Components.classes["@mozilla.org/observer-service;1"]
  655.                        .getService(Components.interfaces.nsIObserverService);
  656.     var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
  657.                                .createInstance(Components.interfaces.nsISupportsPRBool);
  658.     os.notifyObservers(cancelQuit, "quit-application-requested", "restart");
  659.  
  660.     // Something aborted the quit process.
  661.     if (!cancelQuit.data) {
  662.       var nsIAppStartup = Components.interfaces.nsIAppStartup;
  663.       var appStartup = Components.classes["@mozilla.org/toolkit/app-startup;1"]
  664.                                  .getService(nsIAppStartup);
  665.       appStartup.quit(nsIAppStartup.eAttemptQuit | nsIAppStartup.eRestart);
  666.       return true;
  667.     }
  668.   }
  669.  
  670.   // don't refresh if no plugins were found or installed
  671.   if ((gPluginInstaller.mSuccessfullPluginInstallation > 0) &&
  672.       (gPluginInstaller.mPluginInfoArray.length != 0) &&
  673.       gPluginInstaller.mBrowser) {
  674.     // notify listeners that a plugin is installed,
  675.     // so that they can reset the UI and update the browser.
  676.     var event = document.createEvent("Events");
  677.     event.initEvent("NewPluginInstalled", true, true);
  678.     gPluginInstaller.mBrowser.dispatchEvent(event);
  679.   }
  680.  
  681.   return true;
  682. }
  683.